"""
Created on 2024-08-23
@author:LiuFei
@description:
# 初始化
"""
import os
import json
import logging
import django
from django.contrib.auth import get_user_model
from pathlib import Path
from django.db import transaction
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings")
# django.setup()
from yc_django_utils.core_initialize import CoreInitialize
from ..models import Dept, Menu, MenuButton, MenuField, Dictionary, SystemConfig
from .initSerializer import (RoleInitSerializer, MenuButtonInitSerializer, ApiWhiteListInitSerializer,
                             DictionaryInitSerializer,
                             SystemConfigInitSerializer, RoleMenuInitSerializer, RoleMenuButtonInitSerializer,
                             MenuFieldInitSerializer
                             )

Users = get_user_model()
logger = logging.getLogger()
"""数据文件所在目录路径"""
DATA_DIR = Path(__file__).resolve().parent


class Initialize(CoreInitialize):

    def init_dept(self):
        """
        初始化部门信息
        """
        unique_fields = ['name', 'key']
        path_file = os.path.join(DATA_DIR, "init_dept.json")
        if not os.path.isfile(path_file):
            logger.info(f"文件不存在，跳过初始化:{path_file}")
            return
        with open(path_file, encoding="utf-8") as f:
            code_list = json.load(f)

        self.write_tree_dept(code_list, unique_fields=unique_fields)
        logger.info(f"Dept初始化完成")

    @transaction.atomic
    def write_tree_dept(self, data, parent=None, unique_fields=None):
        """
        递归初始化部门信息
        需要处理关联用户信息
        :param data:
        :param parent:
        :param unique_fields:
        :return:
        """
        for item in data:
            children = item.pop('children', [])
            user_list = []
            user_usernames = item.get('user_username', [])
            if user_usernames:
                user_list = Users.objects.filter(username__in=user_usernames)
            filter_data = {}
            for field in unique_fields:
                if field in item:
                    filter_data[field] = item[field]
            # logger.info(f"查找条件[{filter_data}]")
            # 原来就有的数据，则更新，
            instance = Dept.objects.filter(**filter_data).first()
            if instance:
                for i, v in item.items():
                    # 列表和空单独处理
                    if isinstance(v, list) or not v:
                        continue
                    setattr(instance, i, v)
                # logger.info(f"更新[{instance}]")
                instance.save()
            else:
                conditions = {}
                for key, value in item.items():
                    # 列表和空单独处理
                    if isinstance(value, list) or not value:
                        continue
                    conditions[key] = value
                if parent is None:
                    # logger.info(f"创建root[{conditions}]")
                    instance = Dept.add_root(**conditions)
                else:
                    # logger.info(f"创建child[{conditions}]")
                    instance = parent.add_child(**conditions)
            if user_list:
                instance.user.add(*user_list)
                instance.save()
            if children:
                self.write_tree_dept(children, parent=instance, unique_fields=unique_fields)

    def init_role(self):
        """
        初始化角色信息
        """
        self.init_base(RoleInitSerializer, unique_fields=['key'])

    def init_menu(self):
        """
        初始化菜单信息
        """
        # self.init_base(MenuInitSerializer, unique_fields=['name', 'web_path', 'component', 'component_name'])
        unique_fields = ['name', 'web_path']  # , 'component', 'component_name'
        path_file = os.path.join(DATA_DIR, "init_menu.json")
        if not os.path.isfile(path_file):
            logger.info(f"文件不存在，跳过初始化:{path_file}")
            return
        with open(path_file, encoding="utf-8") as f:
            code_list = json.load(f)

        self.write_tree_menu(code_list, unique_fields=unique_fields)
        logger.info(f"Menu初始化完成")

    @transaction.atomic
    def write_tree_menu(self, data, parent=None, unique_fields=None):
        """
        递归初始化菜单信息
        需要处理菜单权限和菜单字段
        :param data:
        :param parent:
        :param unique_fields:
        :return:
        """
        for item in data:
            children = item.pop('children', [])
            menu_button = item.get('menu_button', [])
            menu_field = item.get('menu_field', [])
            filter_data = {}
            for field in unique_fields:
                if field in item:
                    filter_data[field] = item[field]
            # logger.info(f"查找条件[{filter_data}]")
            # 原来就有的数据，则更新，
            instance = Menu.objects.filter(**filter_data).first()
            if instance:
                for i, v in item.items():
                    # 列表和空单独处理
                    if isinstance(v, list) or not v:
                        continue
                    setattr(instance, i, v)
                # logger.info(f"更新[{instance}]")
                instance.save()
            else:
                conditions = {}
                for key, value in item.items():
                    # 列表和空单独处理
                    if isinstance(value, list) or not value:
                        continue
                    conditions[key] = value
                if parent is None:
                    # logger.info(f"创建root[{conditions}]")
                    instance = Menu.add_root(**conditions)
                else:
                    # logger.info(f"创建child[{conditions}]")
                    instance = parent.add_child(**conditions)
            if menu_button:
                for menu_button_data in menu_button:
                    menu_button_data['menu'] = instance.id
                    filter_data = {
                        "menu": menu_button_data['menu'],
                        "value": menu_button_data['value']
                    }
                    instance_obj = MenuButton.objects.filter(**filter_data).first()
                    serializer = MenuButtonInitSerializer(instance_obj, data=menu_button_data, request=self.request)
                    serializer.is_valid(raise_exception=True)
                    serializer.save()
            if menu_field:
                for field_data in menu_field:
                    field_data['menu'] = instance.id
                    filter_data = {
                        'menu': field_data['menu'],
                        'field_name': field_data['field_name'],
                        'model': field_data['model']
                    }
                    instance_obj = MenuField.objects.filter(**filter_data).first()
                    serializer = MenuFieldInitSerializer(instance_obj, data=field_data, request=self.request)
                    serializer.is_valid(raise_exception=True)
                    serializer.save()
            if children:
                self.write_tree_menu(children, parent=instance, unique_fields=unique_fields)

    def init_role_menu(self):
        """
        初始化角色菜单信息
        """
        self.init_base(RoleMenuInitSerializer, unique_fields=['role__key', 'menu__web_path', 'menu__component_name'])

    def init_role_menu_button(self):
        """
        初始化角色菜单按钮信息
        """
        self.init_base(RoleMenuButtonInitSerializer, unique_fields=['role__key', 'menu_button__value'])

    def init_api_white_list(self):
        """
        初始API白名单
        """
        self.init_base(ApiWhiteListInitSerializer, unique_fields=['url', 'method', ])

    def init_dictionary(self):
        """
        初始化字典表
        """
        # self.init_base(DictionaryInitSerializer, unique_fields=['value', 'parent', ])
        self.init_treebeard(Dictionary, unique_fields=["value"])

    def init_system_config(self):
        """
        初始化系统配置表
        """
        # self.init_base(SystemConfigInitSerializer, unique_fields=['key', 'parent', ])
        self.init_treebeard(SystemConfig, unique_fields=["key"])

    def run(self):
        self.init_dept()
        self.init_role()
        self.init_menu()
        self.init_role_menu()
        self.init_role_menu_button()
        self.init_api_white_list()
        self.init_dictionary()
        self.init_system_config()


if __name__ == "__main__":
    Initialize(app='yc_django_mrbac').run()
